﻿using System.Security.Cryptography;
using System.Text;

namespace Leo.Common.RabbitMQ
{
     /// <summary>
     /// 队列绑定
     /// </summary>
    public class RabbitQueueBinder
    {
        public RabbitQueueBinder(RabbitExchangeInfo exchange, RabbitQueueInfo queue, string routingKey)
        {
            if (string.IsNullOrEmpty(routingKey))
            {
                throw new ArgumentNullException("routingKey");
            }
            if (exchange == null)
            {
                throw new ArgumentNullException("exchange");
            }
            if (queue == null)
            {
                throw new ArgumentNullException("queue");
            }
            this.Exchange = exchange;
            this.RoutingKey = routingKey;
            this.Queue = queue;
            this.Queue.AddBinder(this);
        }

        public RabbitQueueInfo Queue { get; set; }

        public RabbitExchangeInfo Exchange { get; set; }

        public string RoutingKey { get; set; }

        public string GetPseudoUrl()
        {
            return string.Concat(new string[]
            {
                this.Exchange.ExchangeType.GetStringValue(),
                "://",
                this.Exchange.Name,
                "/",
                this.RoutingKey
            });
        }

        //[NullableContext(2)]
        public override bool Equals(object obj)
        {
            if (!object.Equals(obj, null))
            {
                RabbitQueueBinder rabbitQueueBinder = obj as RabbitQueueBinder;
                if (rabbitQueueBinder != null)
                {
                    return this.Queue.Name == rabbitQueueBinder.Queue.Name && this.Exchange.Name == rabbitQueueBinder.Exchange.Name && this.RoutingKey == rabbitQueueBinder.RoutingKey;
                }
            }
            return false;
        }

        public override int GetHashCode()
        {
            return this.Queue.Name.GetHashCode() ^ this.Exchange.Name.GetHashCode() ^ this.RoutingKey.GetHashCode();
        }

        //[NullableContext(2)]
        public static bool operator ==(RabbitQueueBinder left, RabbitQueueBinder right)
        {
            bool flag = object.Equals(left, null);
            bool flag2 = object.Equals(right, null);
            return (flag && flag2) || (!flag && !flag2 && left.Equals(right));
        }

        //[NullableContext(2)]
        public static bool operator !=(RabbitQueueBinder left, RabbitQueueBinder right)
        {
            return !(left == right);
        }

        internal string GetRetryDestination()
        {
            string routingKey = this.GenerateRetryRoutingKey();
            return this.Exchange.GetRetryDestination(routingKey);
        }

        internal RabbitQueueBinder GetRetryBinder()
        {
            return new RabbitQueueBinder(this.Exchange, this.Queue, this.GenerateRetryRoutingKey());
        }

        private string GenerateRetryRoutingKey()
        {
            byte[] array = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(this.Queue.Name));
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < 8; i++)
            {
                stringBuilder.Append(Convert.ToString(array[i], 16));
            }
            return "retry-" + stringBuilder.ToString();
        }

        internal RabbitExchangeInfo GenDeadExchange()
        {
            ExchangeWorkMode deadOrRetryExchangeType = Utils.GetDeadOrRetryExchangeType(this.Exchange.ExchangeType.ToString());
            return new RabbitExchangeInfo(Utils.CombineDeadExchangeOrQueueName(this.Exchange.Name), deadOrRetryExchangeType);
        }
    }
}
